﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Security.Principal;
using System.Threading;

using ProjectBase.Core;
using ProjectBase.Core.Service;
using ProjectBase.Core.Web;

using Survey.Entity.Services;
using Survey.Common.Providers;

namespace Survey.Common
{
    /// <summary>
    ///     Provides direct access to the security inforamtion.
    ///     Could be used on any layer.
    /// </summary>
    public static class SecurityManager
    {

        #region Roles

        public static IEnumerable<IControllerAccess> GrantedControllers
        {
            get { return Provider.GetGrantedControllers(); }
        }

        public static IEnumerable<ITVDataItem> GrantedMenuNodes
        {
            get { return Provider.GetGrantedMenuNodes(); }
        }

        public static IEnumerable<string> ExpandedMenuNodes
        {
            get { return Provider.GetExpandedMenuNodes(); }
        }

        public static IEnumerable<string> ApplicationRoles
        {
            get { return Provider.GetApplicationRoles(); }
        }

        public static User User
        {
            get { return Provider.User; }
        }

        public static string UserLogin
        {
            get { return Identity.Name; }
        }

        public static bool HasRole(string roleName)
        {
            return Provider.HasRole(roleName);
        }

        public static bool IsWriteAction(string controllerName, string actionName)
        {
            // WriteAction is set for this Action and Controller
            if (Global.Settings.WriteActions
                .Any(wa => wa.Action.IsEqual(actionName)
                           && wa.Controller.IsNotEmpty()
                           && wa.Controller.IsEqual(controllerName)))
            {
                return true;
            }

            // WriteAction is set for every controller
            if (Global.Settings.WriteActions
                .Any(wa => wa.Action.IsEqual(actionName)
                           && wa.Controller.IsEmpty()))
            {
                return true;
            }

            // this isn't write action
            return false;
        }

        public static void ChangeCurrentRole(string role)
        {
            Provider.ChangeCurrentRole(role);
        }

        public static IEnumerable<string> GetRolesForUser()
        {
            return Provider.GetRolesForUser();
        }

        public static IEnumerable<string> GetRolesForUser(string username)
        {
            return Provider.GetRolesForUser(username);
        }

        #endregion Roles

        #region Identity

        public static IIdentity Identity
        {
            get { return Thread.CurrentPrincipal.Identity; }
        }
        public static bool IsAuthenticationModeForms { get { return Provider.IsAuthenticationModeForms; } }
        public static bool IsAuthenticationModeNone { get { return Provider.IsAuthenticationModeNone; } }

        #endregion Identity

        private static ISecurityProvider Provider { get { return Instance.Provider; } }

        public static bool IsInitialized { get; private set; }

        #region lazy instance

        // beforefieldinit off
        // see: http://www.yoda.arachsys.com/csharp/singleton.html
        // see: http://www.yoda.arachsys.com/csharp/beforefieldinit.html
        private static class Instance
        {
            // beforefieldinit
            public static readonly ISecurityProvider Provider;

            static Instance()
            {
                Provider = Factory.CreateInstance<ISecurityProvider>();
                var user = SecurityManager.User; // TODO fix this ugly way how to force user init
                SecurityManager.IsInitialized = true;
            }
        }

        #endregion lazy instance
    }
}